home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / go / prog / xigcv2_8.taz / xigcv2_8 / igscomm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-08  |  5.5 KB  |  240 lines

  1. /* igscomm.c
  2.  * S.Coffin   USWAT   3/93
  3.  *
  4.  * Simple socket-based comm program for calling the igs
  5.  */
  6.  
  7. /*  Copyright (c) 1992 by Stephen Coffin.  All rights reserved.
  8.  *
  9.  *  This program is distributed in the hope that it will be useful.
  10.  *  Use and copying of this software and preparation of derivative works
  11.  *  based upon this software are permitted, so long as the following
  12.  *  conditions are met:
  13.  *       o credit to the authors is acknowledged following current
  14.  *         academic behavior
  15.  *       o no fees or compensation are charged for use, copies, or
  16.  *         access to this software
  17.  *       o this copyright notice is included intact.
  18.  *  This software is made available AS IS, and no warranty is made about 
  19.  *  the software or its performance. 
  20.  * 
  21.  *  Bug descriptions, use reports, comments or suggestions are welcome.
  22.  *  Send them to    scoffin@advtech.uswest.com
  23.  */
  24.  
  25. #include "igscomm.h"
  26.  
  27. #define USAGE "Usage:  %s [-d] [-?] [-e] [-h host-address] [-p port-number]\n"
  28.  
  29. int dbg = FALSE;
  30. void SCbcopy();
  31. int port = PORT;
  32. int echoflag = TRUE;
  33.  
  34. /* thanks to jpab+@andrew.cmu.edu for providing this function, improving
  35.  * DNS lookups of numeric or logical internet addresses  =SC
  36.  */
  37. long io_lookup_addr( str )
  38.      unsigned char *str;
  39. {
  40.     u_long addr;
  41.     struct hostent *hp;
  42.  
  43.     if( isdigit(str[0]) ) {
  44.     return inet_addr( str );
  45.     }
  46.     else {
  47.     if( (hp = gethostbyname(str)) == NULL ) {
  48.         fprintf( stderr, "can't find the address of '%s'\n", str );
  49.         exit( 1 );
  50.     }
  51.     SCbcopy( hp->h_addr_list[0], &addr, sizeof(struct in_addr) );
  52.     return addr;
  53.     }
  54. }
  55.  
  56. main( argc, argv )
  57.     int argc;
  58.     char *argv[];
  59. {
  60.     int i, j, sd, count, ret;
  61.     unsigned char *r;
  62.     char *host = HOST;
  63.     struct sockaddr_in sin;
  64.     unsigned char str[MSG_SIZE+1];
  65.     fd_set xx;
  66.     struct timeval timeout;
  67.     int yy = 32;
  68.     extern int getopt();
  69.     extern char *optarg;
  70.     extern int optind;
  71.     int c, skipcount = 0;
  72. #ifdef BSD
  73.     struct sgttyb tin, tout;
  74. #else
  75.     struct termio tin, tout;
  76. #endif
  77.  
  78.     while( (c=getopt( argc, argv, "?h:p:de" )) != (-1) ) {
  79.         switch( c ) {
  80.         case 'd':    /* debug mode */
  81.             dbg = TRUE;
  82.             break;
  83.         case 'e':    /* disable echo */
  84.             echoflag = FALSE;
  85.             break;
  86.         case 'p':    /* socket number */
  87.             port = atoi( optarg );
  88.             break;
  89.         case 'h':    /* host id */
  90.             host = optarg;
  91.             break;
  92.         case '?':
  93.         default:
  94.             fprintf( stderr, "%s: Release %s\n", argv[0], PATCHLEVEL );
  95.                 fprintf( stderr, USAGE, argv[0] );
  96.             exit( (-1) );
  97.             break;
  98.         }
  99.     }
  100.  
  101.     if( optind != argc ) {
  102.         fprintf( stderr, "%s: Release %s\n", argv[0], PATCHLEVEL );
  103.         fprintf( stderr, USAGE, argv[0] );
  104.         exit( (-1) );
  105.     }
  106.  
  107.     sin.sin_addr.s_addr = io_lookup_addr( host );
  108.     sin.sin_family = AF_INET;
  109.     sin.sin_port = htons( port );
  110.  
  111.     if( (sd=socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 ) {
  112.         perror( "socket" );
  113.         exit( 2 );
  114.     }
  115.  
  116.     if( connect( sd, (unsigned char *)&sin, sizeof( sin ) ) < 0 ) {
  117.         perror( "connect" );
  118.         exit( 3 );
  119.     }
  120.  
  121.     /* connected now */
  122.  
  123.     /* turn off echo */
  124.     /*XXX  I don't know if this code is ok for ALL UNIX versions */
  125.     if( !echoflag ) {
  126. #ifdef BSD
  127.         ioctl( fileno(stdin), TIOCGETP, &tin );
  128.         tout = tin;
  129.         tout.sg_flags &= ~ECHO;
  130.         ioctl( fileno(stdin), TIOCSETP, &tout );
  131. #else
  132.         ioctl( fileno(stdin), TCGETA, &tin );
  133.         tout = tin;
  134.         tout.c_lflag &= ~ECHO;
  135.         ioctl( fileno(stdin), TCSETAW, &tout );
  136. #endif
  137.     }
  138.  
  139.     for( ;; ) {
  140.         timeout.tv_sec = TIMEOUT;
  141.         timeout.tv_usec = 0L;
  142.         FD_ZERO( &xx );
  143.         FD_SET( sd, &xx );    /* listen on the socket */
  144.         FD_SET( 0, &xx );    /* listen for kbd input */
  145.  
  146.         ret = select( yy, &xx, NULL, NULL, &timeout );
  147.  
  148.         /* error ? */
  149.         if( ret < 0 ) {
  150.             /* exit on interrupt ?? */
  151.         if( errno == EINTR ) break;
  152.  
  153.             /* any other interruption is an error! */
  154.         else {
  155.             perror( "select" );
  156.             break;
  157.         }
  158.         }
  159.  
  160.         /* timeout */
  161.         else if( ret == 0 ) {
  162.         if( dbg ) fprintf( stderr, "Timeout\n" );
  163.         continue;
  164.         }
  165.  
  166.         /* input from socket.... print it */
  167.         else if( FD_ISSET( sd, &xx ) ) {
  168.         FD_CLR( sd, &xx );
  169.             if( (count=recv( sd, str, MSG_SIZE, 0 )) < 0 ) {
  170.             perror( "recv" );
  171.             break;
  172.             }
  173.         if( count == 0 ) {
  174.             fprintf( stderr, "Connection closed by foreign host.\n" );
  175.             break;
  176.         }
  177.  
  178.             str[count] = '\0';
  179.         for( j=0; j < count; ++j ) {
  180.  
  181.             /* igonore 3-char sequences beginning with 0xff */
  182.             if( str[j] == 0xff ) {
  183.             skipcount = 2;
  184.             }
  185.  
  186.             /* answer "are you there" request from server */
  187.             else if( skipcount == 2 && str[j] == 0xf6 ) {
  188.             skipcount = 0;
  189.             sprintf( (char *)str, "\r\n" );
  190.             if( send( sd, str, 2, 0 ) ) {
  191.                     perror( "send" );
  192.                     break;
  193.             }
  194.             }
  195.             else if( skipcount > 0 ) {
  196.             --skipcount;
  197.             }
  198.             else putchar( str[j] );
  199.         }
  200.         fflush( stdout );
  201.         continue;
  202.         }
  203.  
  204.         /* input from keyboard....  send it */
  205.         else if( FD_ISSET( 0, &xx ) ) {
  206.         FD_CLR( 0, &xx );
  207.             if( (r = (unsigned char *)gets( (char *)str )) == NULL ) break;
  208.             j = strlen( (char *)str );
  209.             if( str[0] == '.' && j == 1 ) break;
  210.             str[j++] = '\r';
  211.             str[j++] = '\n';
  212.             str[j+1] = '\0';
  213.  
  214.             /* send a message to the server PORT on HOST */
  215.             if( send( sd, str, j, 0 ) < 0 ) {
  216.             perror( "send" );
  217.             break;
  218.             }
  219.         continue;
  220.         }
  221.     }
  222.  
  223.     /* close the socket connection */
  224.     if( shutdown( sd, 2 ) < 0 ) {
  225.         perror( "shutdown" );
  226.         exit( 1 );
  227.     }
  228.  
  229.     close( sd );
  230. }
  231.  
  232. /* really crude, unsafe version of bcopy() */
  233. void SCbcopy( b1, b2, length )
  234.     register unsigned char *b1;
  235.     register unsigned char *b2;
  236.     register unsigned length;
  237. {
  238.     while( length-- > 0 ) *b2++ = *b1++;
  239. }
  240.